package cn.edu.xmu.oomall.aftersale.controller;

import cn.edu.xmu.oomall.aftersale.model.bo.AftersaleState;
import cn.edu.xmu.oomall.aftersale.model.vo.*;
import cn.edu.xmu.oomall.aftersale.service.AfterSaleService;
import cn.edu.xmu.oomall.core.util.Common;
import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.privilegegateway.annotation.aop.Audit;
import cn.edu.xmu.privilegegateway.annotation.aop.LoginName;
import cn.edu.xmu.privilegegateway.annotation.aop.LoginUser;
import cn.edu.xmu.privilegegateway.annotation.util.InternalReturnObject;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;

/**
 * @author X-Raymond
 * @date 2021/12/9
 */
@RestController
@RequestMapping(value = "/", produces = "application/json;charset=UTF-8")
public class AfterSaleController {

    @Autowired
    private AfterSaleService afterSaleService;


    /**
     * 获得售后单的所有状态
     *
     * @return List<Map < String, Object>>
     */
    @ApiOperation(value = "获得售后的所有状态")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "成功")})
    @GetMapping("/aftersales/states")
    public Object getAllState() {
        ReturnObject returnObject = afterSaleService.getAllState();
        return Common.decorateReturnObject(returnObject);
    }

    /**
     * @param beginTime
     * @param endTime
     * @param state
     * @param page
     * @param pageSize
     * @return
     */
    @Audit
    @GetMapping("/aftersales")
    public Object getOwnAftersales(@LoginUser Long userId,
                                   @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) @RequestParam(required = false) LocalDateTime beginTime,
                                   @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) @RequestParam(required = false) LocalDateTime endTime,
                                   @RequestParam(required = false) Integer state,
                                   @RequestParam(required = false, defaultValue = "1") Integer page,
                                   @RequestParam(required = false, defaultValue = "5") Integer pageSize
    ) {
        //合法性检查，判断开始时间和结束时间
        if (!(beginTime == null || endTime == null)) {
            if (beginTime.compareTo(endTime) > 0) {
                return Common.decorateReturnObject(new ReturnObject<>(ReturnNo.LATE_BEGINTIME));
            }
        }
        if (state != null) {
            if (state > AftersaleState.CANCEL.getCode() || state < 0) {
                return Common.decorateReturnObject(new ReturnObject<>(ReturnNo.FIELD_NOTVALID, "state错误"));
            }
        }
        return Common.decorateReturnObject(afterSaleService.getOwnAftersales(userId, beginTime, state, endTime, page, pageSize));
    }

    /**
     * 管理员查看售后单
     *
     * @param id
     * @param beginTime
     * @param endTime
     * @param state
     * @param type
     * @param page
     * @param pageSize
     * @return
     */
    @Audit
    @GetMapping("/shops/{id}/aftersales")
    public Object getAftersales(@PathVariable(value = "id", required = true) Long id,
                                @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) @RequestParam(required = false) LocalDateTime beginTime,
                                @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) @RequestParam(required = false) LocalDateTime endTime,
                                @RequestParam(required = false) Integer state,
                                @RequestParam(required = false) Integer type,
                                @RequestParam(required = false, defaultValue = "1") Integer page,
                                @RequestParam(required = false, defaultValue = "5") Integer pageSize
    ) {
        //合法性检查，判断开始时间和结束时间
        if (beginTime != null && endTime != null) {
            if (beginTime.compareTo(endTime) > 0) {
                return Common.decorateReturnObject(new ReturnObject<>(ReturnNo.LATE_BEGINTIME));
            }
        }
        if (state != null) {
            if (state > AftersaleState.CANCEL.getCode() || state < 0) {
                return Common.decorateReturnObject(new ReturnObject<>(ReturnNo.FIELD_NOTVALID, "state错误"));
            }
        }
        int fixed = 2;
        if (type != null) {
            if (type > fixed || type < 0) {
                return Common.decorateReturnObject(new ReturnObject<>(ReturnNo.FIELD_NOTVALID, "type错误"));
            }
        }
        if (id != null && id <= 0) {
            return Common.decorateReturnObject(new ReturnObject<>(ReturnNo.FIELD_NOTVALID, "shopId错误"));
        }
        return Common.decorateReturnObject(afterSaleService.getAftersales(id, beginTime, state, endTime, type, pageSize, page));
    }

    /**
     * 用户根据id查询自己的售后
     *
     * @param id
     * @return
     */
    @Audit
    @ApiOperation(value = "查询售后")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "authorization", value = "token", required = true, dataType = "String", paramType = "header"),
            @ApiImplicitParam(name = "id", value = "售后Id", required = true, dataType = "Long", paramType = "query")
    })
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "成功")})
    @GetMapping(value = "/aftersales/{id}")

    public Object getOwnAftersalesById(@LoginUser Long loginUserId,
                                       @PathVariable(value = "id", required = true) Long id) {
        if (id != null && id <= 0) {
            return Common.decorateReturnObject(new ReturnObject<>(ReturnNo.FIELD_NOTVALID, "id错误"));
        }
        return Common.decorateReturnObject(afterSaleService.getOwnAftersalesById(loginUserId, id));
    }

    /**
     * 管理员根据id查看售后信息
     *
     * @param shopId
     * @param id
     * @return
     */
    @Audit
    @GetMapping(value = "/shops/{shopId}/aftersales/{id}")
    public Object getAftersalesById(@PathVariable(value = "shopId") Long shopId,
                                    @PathVariable(value = "id") Long id) {
        if (shopId != null && shopId <= 0) {
            return Common.decorateReturnObject(new ReturnObject<>(ReturnNo.FIELD_NOTVALID, "shopId错误"));
        }
        if (id != null && id <= 0) {
            return Common.decorateReturnObject(new ReturnObject<>(ReturnNo.FIELD_NOTVALID, "id错误"));
        }
        return Common.decorateReturnObject(afterSaleService.getAftersalesByShopIdAndId(shopId, id));
    }

    /**
     * 用户修改售后单信息（店家生成售后单前）
     *
     * @param id
     * @return
     */
    @Audit
    @PutMapping(value = "/aftersales/{id}")
    public Object modifyOwnAftersaleById(@LoginUser Long userId,
                                         @LoginName String userName,
                                         @PathVariable(value = "id") Long id,
                                         @RequestBody AftersaleModifyVo aftersaleModifyVo) {
        if (id != null && id <= 0) {
            return Common.decorateReturnObject(new ReturnObject<>(ReturnNo.FIELD_NOTVALID, "id错误"));
        }
        ReturnObject returnObject = afterSaleService.modifyOwnAftersaleById(userId, userName, id, aftersaleModifyVo);
        return Common.decorateReturnObject(returnObject);
    }

    /**
     * 用户寄回货物后添加运单号
     *
     * @param userId
     * @param id
     * @param customerLogSnVo
     * @return
     */
    @Audit
    @PutMapping(value = "/aftersales/{id}/sendback")
    public Object addUserLogSn(@LoginUser Long userId,
                               @LoginName String userName,
                               @PathVariable(value = "id") Long id,
                               @RequestBody CustomerLogSnVo customerLogSnVo) {
        if (id != null && id <= 0) {
            return Common.decorateReturnObject(new ReturnObject<>(ReturnNo.FIELD_NOTVALID, "id错误"));
        }
        ReturnObject returnObject = afterSaleService.addUserLogSn(userId, userName, id, customerLogSnVo);
        return Common.decorateReturnObject(returnObject);
    }

    /**
     * 用户确认售后单结束
     *
     * @param userId
     * @param id
     * @return
     */
    @Audit
    @PutMapping(value = "/aftersales/{id}/confirm")
    public Object userConfirmEnd(@LoginUser Long userId,
                                 @LoginName String userName,
                                 @PathVariable(value = "id") Long id) {
        ReturnObject returnObject = afterSaleService.userConfirmEnd(userId, userName, id);
        return Common.decorateReturnObject(returnObject);
    }

    /**
     * 管理员同意或不同意售后单
     *
     * @param shopId
     * @param id
     * @param shopConfirmVo
     * @return
     */
    @Audit
    @PutMapping(value = "/shops/{shopId}/aftersales/{id}/confirm")
    public Object shopConfirmAftersales(@LoginUser Long userId,
                                        @LoginName String userName,
                                        @PathVariable(value = "shopId") Long shopId,
                                        @PathVariable(value = "id") Long id,
                                        @RequestBody ShopConfirmVo shopConfirmVo) {
        ReturnObject returnObject = afterSaleService.shopConfirmAftersales(userId, userName, shopId, id, shopConfirmVo);
        return Common.decorateReturnObject(returnObject);
    }

    /**
     * 管理员验收
     *
     * @param shopId
     * @param id
     * @param shopReceiveVo
     * @return
     */
    @Audit
    @PutMapping(value = "/shops/{shopId}/aftersales/{id}/receive")
    public Object shopConfirmAftersales(@LoginUser Long userId,
                                        @LoginName String userName,
                                        @PathVariable(value = "shopId") Long shopId,
                                        @PathVariable(value = "id") Long id,
                                        @RequestBody ShopReceiveVo shopReceiveVo) {
        ReturnObject returnObject = afterSaleService.shopReceiveAftersales(userId, userName, shopId, id, shopReceiveVo);
        return Common.decorateReturnObject(returnObject);
    }

    /**
     * 卖家发货
     *
     * @param shopId
     * @param id
     * @param shopLogSnVo
     * @return
     */
    @Audit
    @PutMapping(value = "/shops/{shopId}/aftersales/{id}/deliver")
    public Object shopDeliverAftersales(@LoginUser Long userId,
                                        @LoginName String userName,
                                        @PathVariable(value = "shopId") Long shopId,
                                        @PathVariable(value = "id") Long id,
                                        @RequestBody ShopLogSnVo shopLogSnVo) {
        ReturnObject returnObject = afterSaleService.shopDeliverAftersales(userId, userName, shopId, id, shopLogSnVo);
        return Common.decorateReturnObject(returnObject);
    }

    /**
     * 用户新建售后单
     *
     * @param orderItemId
     * @param userName
     * @param userId
     * @param aftersaleAddVo
     * @return
     */
    @Audit
    @PostMapping(value = "/orderitems/{id}/aftersales")
    public Object userAddAftersales(@PathVariable(value = "id") Long orderItemId,
                                    @LoginName String userName,
                                    @LoginUser Long userId,
                                    @RequestBody AftersaleAddVo aftersaleAddVo) {
        int fixed = 2;
        Byte type = aftersaleAddVo.getType();
        if (type != null) {
            if (type > fixed || type < 0) {
                return Common.decorateReturnObject(new ReturnObject<>(ReturnNo.FIELD_NOTVALID, "type错误"));
            }
        }
        if (aftersaleAddVo.getQuantity() < 0) {
            return Common.decorateReturnObject(new ReturnObject<>(ReturnNo.FIELD_NOTVALID, "quantity错误"));
        }
        ReturnObject returnObject = afterSaleService.userAddAftersales(userName, userId, orderItemId, aftersaleAddVo);
        return Common.decorateReturnObject(returnObject);
    }

    /**
     * 用户逻辑删除或取消售后单
     *
     * @param id
     * @param userId
     * @return
     */
    @Audit
    @DeleteMapping(value = "/aftersales/{id}")
    public Object userLogicDeleteAftersalesById(@PathVariable(value = "id") Long id,
                                                @LoginUser Long userId) {
        ReturnObject returnObject = afterSaleService.userLogicDeleteAftersalesById(userId, id);
        return Common.decorateReturnObject(returnObject);
    }

    /**
     * 获得售后单的支付信息
     *
     * @param userId
     * @param userName
     * @param id
     * @return
     */
    @Audit
    @GetMapping(value = "/aftersales/{id}/payments")
    public Object getPaymentsById(@LoginUser Long userId,
                                  @LoginName String userName,
                                  @PathVariable(value = "id") Long id) {
        ReturnObject returnObject = afterSaleService.getPaymentBydId(userId, userName, id);
        return returnObject;
    }


    /**
     * 内部获取售后单
     *
     * @param id
     * @return
     */
    @GetMapping(value = "/internal/aftersales/{id}")
    public Object getAftersalesById(@PathVariable(value = "id") Long id) {
        if (id != null && id <= 0) {
            return new InternalReturnObject(ReturnNo.FIELD_NOTVALID.getCode(), "id错误");
        }
        return Common.decorateReturnObject(afterSaleService.getAftersalesById(id));
    }

}
